﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using YoloPredictor;

namespace FruitDetectorDemoForWin
{
    public partial class Form1 : Form
    {
        private IPredictor pred;
        private Bitmap picture;
        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;//关闭UI线程安全检查
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            pred = PredictorLib.CreateDefaultPredictor(new PredictorConfig()
            {
                UseCUDA = false,
                Names = "./module/obj.names",
                Config = "./module/detector.cfg",
                Weights = "./module/detector.weights",
                NmsThreshold = 0.3f,
                Threshold = 0.5f
            });
        }

        Dictionary<string, Prediction> preds = new Dictionary<string, Prediction>();

        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            lock (pred) { }//predictor在运行时不允许再次调用
            results.Items.Clear();
            preds.Clear();
            String[] files = e.Data.GetData(DataFormats.FileDrop, false) as String[];
            picture = ResizeImage((Bitmap)Bitmap.FromFile(files[0]), 300);
            rawpic.Image = picture;
            new Thread(new ThreadStart(() =>
            {
                lock (pred)
                {//保证predictor不会被重复调用
                    var predictions = pred.Predict(new OpenCvSharp.Mat(files[0]));
                    int id = 0;
                    results.BeginUpdate();
                    foreach (var predic in predictions)
                    {
                        preds.Add(id + "_" + predic.ClassName, predic);
                        results.Items.Add(id + "_" + predic.ClassName);
                        id++;
                    }
                    results.EndUpdate();
                }
            })).Start();
        }

        public static Bitmap ResizeImage(Bitmap bmp, int newW)
        {
            try
            {
                int newH = (int)(bmp.Height * ((float)newW / bmp.Height));
                Bitmap b = new Bitmap(newW, newH);
                Graphics g = Graphics.FromImage(b);

                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                g.Dispose();

                return b;
            }
            catch
            {
                return null;
            }
        }

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void results_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                var prediction = preds[results.SelectedItem.ToString()];
                respicbox.Image = picture.Clone(new Rectangle()
                {
                    X = (int)(prediction.Box.X - prediction.Box.Width / 2),
                    Y = (int)(prediction.Box.Y - prediction.Box.Height / 2),
                    Height = (int)prediction.Box.Height,
                    Width = (int)prediction.Box.Width
                }, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            }
            catch (Exception err)
            {

            }
        }
    }
}
